﻿#include "exprvalue.h"
#include "global.h"
#include <QDateTime>

//名字的类型，值类型是否可以兼容。>=0 可以，< 0 非法
//即把valueType 给 nameType
//pSym = exprValue 把表达式赋值给符号表中的值
//autoTransType 是否需要自动转换类型，如果是，则后续expr需要自动转换
//nameType 需要的类型
//valueType 当前的类型。
//expr需要转换的表达式。
int exprTypeMatch(int nameType, int valueType, bool iswarn,bool autoTransType, ExprValue* expr)
{
    int ret = EXPR_to_Err;
    int type  = nameType << 16 | valueType;

    switch(type)
    {
    case EXPR_STRING << 16 | EXPR_INT:
        ret = EXPR_Int_to_String;//整数转字符串，非法，下同
        break;
    case EXPR_STRING << 16 | EXPR_INT64:
        ret = EXPR_Int64_to_String; //整数转字符串，非法，下同
        break;
    case EXPR_STRING << 16 | EXPR_FLOAT:
        ret = EXPR_Float_to_String; //整数转字符串，非法，下同
        break;
    case EXPR_INT << 16 | EXPR_STRING:
        ret = EXPR_String_to_Int;
        break;
    case EXPR_INT64 << 16 | EXPR_STRING:
        ret = EXPR_String_to_Int64;
        break;
    case EXPR_FLOAT << 16 | EXPR_STRING:
        ret = EXPR_String_to_Float;
        break;

        //下面是合法的，不过有些会精度丢失
    case EXPR_INT << 16 | EXPR_INT:
        ret = EXPR_Int_to_Int;
        break;
    case EXPR_INT64 << 16 | EXPR_INT:
        ret = EXPR_Int_to_Int64;
        break;
    case EXPR_FLOAT << 16 | EXPR_INT:
        ret = EXPR_Int_to_Float;
        break;

    case EXPR_INT64 << 16 | EXPR_INT64:
        ret = EXPR_Int64_to_Int64;
        break;
    case EXPR_INT << 16 | EXPR_INT64:
        ret = EXPR_Int64_to_Int;
        break;
    case EXPR_FLOAT << 16 | EXPR_INT64:
        ret = EXPR_Int64_to_Float;
        break;

    case EXPR_FLOAT << 16 | EXPR_FLOAT:
        ret = EXPR_Float_to_Float;
        break;

    case EXPR_INT << 16 | EXPR_FLOAT:
        ret = EXPR_Float_to_Int;
        break;
    case EXPR_INT64 << 16 | EXPR_FLOAT:
        ret = EXPR_Float_to_Int64;
        break;

    case EXPR_STRING << 16 | EXPR_STRING:
        ret = EXPR_String_to_String;
        break;

    case EXPR_STRING << 16 | EXPR_CHAR:
    {
        ret = EXPR_Char_to_String;
        if(autoTransType)
        {
            char v(expr->value.vchar);
            expr->type = EXPR_STRING;
            QByteArray* p = new QByteArray();
            p->append(v);
            expr->value.vpoint = p;
#ifdef PIN_MEM_REF
            newTime();
#endif
        }
    }
    break;

    case EXPR_STRING << 16 | EXPR_U16STRING:
    {
        ret = EXPR_U16String_to_String;
        if(autoTransType)
        {
            QString* p = (QString*)expr->value.vpoint;
            QByteArray *pByte = new QByteArray(p->toUtf8());
#ifdef PIN_MEM_REF
            newTime();
#endif
            expr->freeMem();
            expr->type = EXPR_STRING;
            expr->value.vpoint = pByte;
        }
    }
    break;

    case EXPR_U16STRING << 16 | EXPR_U16STRING:
        ret = EXPR_U16String_to_U16String;
        break;

    case EXPR_U16STRING << 16 | EXPR_STRING:
    {
        ret = EXPR_String_to_U16String;

        if(autoTransType)
        {

            QByteArray* p = (QByteArray*)expr->value.vpoint;
            QString *pStr = new QString(*p);
#ifdef PIN_MEM_REF
            newTime();
#endif
            expr->freeMem();
            expr->type = EXPR_U16STRING;
            expr->value.vpoint = pStr;
        }
    }
        break;

    case EXPR_BOOL << 16 | EXPR_BOOL:
        ret = EXPR_Bool_to_Bool;
        break;
    case EXPR_STRUCT << 16 | EXPR_STRUCT:
        ret = EXPR_Struct_to_Struct;
        break;
    case EXPR_LIST << 16 | EXPR_LIST:
        ret = EXPR_List_to_List;
        break;
    case EXPR_MAP << 16 | EXPR_MAP:
        ret = EXPR_Map_to_Map;
        break;

    case EXPR_FILE << 16 | EXPR_FILE:
        ret = EXPR_File_to_File;
        break;

    case EXPR_DATE << 16 | EXPR_DATE:
        ret = EXPR_Date_to_Date;
        break;
    case EXPR_FUN << 16 | EXPR_FUN:
        ret = EXPR_Fun_to_Fun;
        break;

    case EXPR_CHAR << 16 | EXPR_CHAR:
        ret = EXPR_Char_to_Char;
        break;

    case EXPR_WCHAR << 16 | EXPR_WCHAR:
        ret = EXPR_WChar_to_WChar;
        break;

    case EXPR_WCHAR << 16 | EXPR_CHAR:
    {
        ret = EXPR_Char_to_WChar;
        if(autoTransType)
        {
            expr->type = EXPR_WCHAR;
            expr->value.vwchar = expr->value.vchar;
        }
    }
        break;

    case EXPR_WCHAR << 16 | EXPR_INT:
    {
        ret = EXPR_Int_to_WChar;
        if(autoTransType)
        {
            expr->type = EXPR_WCHAR;
            expr->value.vwchar = expr->value.vint;
        }
    }
        break;

    case EXPR_INT << 16 | EXPR_CHAR:
    {
        ret = EXPR_Char_to_Int;
        if(autoTransType)
        {
            expr->type = EXPR_INT;
            expr->value.vint = expr->value.vchar;
        }
    }
        break;

    case EXPR_INT << 16 | EXPR_WCHAR:
    {
        ret = EXPR_WChar_to_Int;
        if(autoTransType)
        {
            expr->type = EXPR_INT;
            expr->value.vint = expr->value.vwchar;
        }
    }
        break;

    case EXPR_INT64 << 16 | EXPR_CHAR:
    {
        ret = EXPR_Char_to_Int64;
        if(autoTransType)
        {
            expr->type = EXPR_INT64;
            expr->value.vint64 = expr->value.vchar;
        }
    }
        break;

    case EXPR_INT64 << 16 | EXPR_WCHAR:
    {
        ret = EXPR_WChar_to_Int64;
        if(autoTransType)
        {
            expr->type = EXPR_INT64;
            expr->value.vint64 = expr->value.vwchar;
        }
    }
        break;



    case EXPR_U16STRING << 16 | EXPR_CHAR:
    {
        ret = EXPR_Char_to_U16String;
        if(autoTransType)
        {
            QChar v(expr->value.vchar);
            expr->type = EXPR_U16STRING;
            expr->value.vpoint = new QString(v);
#ifdef PIN_MEM_REF
            newTime();
#endif
        }
    }
        break;

    case EXPR_U16STRING << 16 | EXPR_WCHAR:
    {
        ret = EXPR_WChar_to_U16String;
        if(autoTransType)
        {
            QChar v(expr->value.vwchar);
            expr->type = EXPR_U16STRING;
            expr->value.vpoint = new QString(v);
#ifdef PIN_MEM_REF
            newTime();
#endif
        }
    }
        break;


    //字符串可作为路径转换为文件
    case EXPR_FILE << 16 | EXPR_STRING:
        ret = EXPR_String_to_File;
        break;
    default:
        break;
    }
    if(iswarn && ret < 0)
    {
        std::cout << u8"变量的类型和其赋值无法匹配！请检查。" << std::endl;
    }

    return ret;
}

void freeRefObjMem(ExprValue* expr)
{
    switch (expr->type)
    {
        case EXPR_FILE:
        case EXPR_LIST:
        case EXPR_MAP:
        case EXPR_EXCEL:
        {
            expr->freeMem();
        }
        break;
    }
}

//QMap<std::string, char*> ExprValue::s_packName_map;

ExprValue::ExprValue()
{
    value.vint64 = 0;//初始化为0
    type = EXPR_ERR;
    varName = nullptr;
}

ExprValue::ExprValue(std::string str)
{
    type = EXPR_STRING;
    varName = nullptr;
    value.vpoint = new QByteArray(QByteArray::fromStdString(str));
#ifdef PIN_MEM_REF
    newTime();
#endif
}

std::string ExprValue::getString()
{
    return ((QByteArray*)(this->value.vpoint))->toStdString();

}

const std::string ExprValue::getPackName() const //获取全局包名，即vtype
{
    switch(value.vpacktype)
    {
    case EXPR_FILE: //现在只使用了文件。
        return "wj::";

    case EXPR_CHAR:
        return "zf::";

    case EXPR_STRING:
        return "zfc::";

    default:
    {
        QString err = QString("错误:未定义的包类型");
        AbortException(err);
    }

    }

    return std::string();
}

//返回文件的路径
std::string ExprValue::getFilePath()
{
    if(value.vpoint != nullptr)
    {
        FILE_VALUE_DATA* pData = (FILE_VALUE_DATA*)this->value.vpoint;
        if(pData->pFileInfo != nullptr)
        {
            return pData->pFileInfo->absoluteFilePath().toStdString();
        }
    }
    return "";
}

//设置字符串类型的值。
void ExprValue::setString(std::string str,bool needFree)
{
    this->type = EXPR_STRING;

    if (!needFree && value.vpoint == nullptr)
    {
        value.vpoint = new QByteArray(QByteArray::fromStdString(str));
#ifdef PIN_MEM_REF
        newTime();
#endif
    }
    else
    {
        if (value.vpoint != nullptr)
        {
            QByteArray* pData = (QByteArray*)(value.vpoint);
            pData->clear();
            pData->append(QByteArray::fromStdString(str));
        }
    }
}

void ExprValue::setStringBytes(QByteArray& bytes)
{
    this->type = EXPR_STRING;

    if (value.vpoint == nullptr)
    {
        value.vpoint = new QByteArray(bytes);
#ifdef PIN_MEM_REF
        newTime();
#endif
    }
    else
    {
        QByteArray* pData = (QByteArray*)(value.vpoint);
        pData->clear();
        pData->append(bytes);

    }
}

std::string& ExprValue::getStructName()
{
    return ((STRUCT_VALUE_DATA*)(this->value.vpoint))->structType;
}

int ExprValue::getStructTypeId()
{
    return ((STRUCT_VALUE_DATA*)(this->value.vpoint))->structTypeId;
}

//可以对比，0 相等 -1小于 1 大于 2 不等。-100：非法不能对比
int CompareExprAndExpr(ExprValue& pSym, ExprValue& expr, bool iswarn)
{
    int ret = CAN_NOT_CMP;
    int type = (pSym.type << 16) | expr.type;

    switch (type)
    {
    case EXPR_STRING << 16 | EXPR_INT64:
    case EXPR_STRING << 16 | EXPR_INT:
    case EXPR_INT << 16 | EXPR_STRING:
    case EXPR_INT64 << 16 | EXPR_STRING:
        if (iswarn)
        {
            std::cout << u8"字符串和整数不能进行逻辑比对大小运算" << std::endl;
        }
        break;

    case EXPR_STRING << 16 | EXPR_FLOAT:
    case EXPR_FLOAT << 16 | EXPR_STRING:
        if (iswarn)
        {
            std::cout << u8"字符串和小数不能进行逻辑比对大小运算" << std::endl;
        }
        break;

        //整数和整数对比
    case EXPR_INT << 16 | EXPR_INT:
        ret = (pSym.value.vint == expr.value.vint) ? EQUAL_STATUS : ((pSym.value.vint > expr.value.vint) ? GREATER_STATUS : LESS_STATUS);
        break;

    case EXPR_INT64 << 16 | EXPR_INT:
        ret = (pSym.value.vint64 == expr.value.vint) ? EQUAL_STATUS : ((pSym.value.vint64 > expr.value.vint) ? GREATER_STATUS : LESS_STATUS);
        break;

    case EXPR_FLOAT << 16 | EXPR_INT:
        ret = (pSym.value.vfloat == expr.value.vint) ? EQUAL_STATUS : ((pSym.value.vfloat > expr.value.vint) ? GREATER_STATUS : LESS_STATUS);
        break;

    case EXPR_INT64 << 16 | EXPR_INT64:
        ret = (pSym.value.vint64 == expr.value.vint64) ? EQUAL_STATUS : ((pSym.value.vint64 > expr.value.vint64) ? GREATER_STATUS : LESS_STATUS);
        break;

    case EXPR_INT << 16 | EXPR_INT64:
        ret = (pSym.value.vint == expr.value.vint64) ? EQUAL_STATUS : ((pSym.value.vint > expr.value.vint64) ? GREATER_STATUS : LESS_STATUS);
        break;

    case EXPR_FLOAT << 16 | EXPR_INT64:
        ret = (pSym.value.vfloat == expr.value.vint64) ? EQUAL_STATUS : ((pSym.value.vfloat > expr.value.vint64) ? GREATER_STATUS : LESS_STATUS);
        break;

        //这里可能有误差，浮点数默认是不能进行等于判断的，需要使用abs
    case EXPR_FLOAT << 16 | EXPR_FLOAT:
        ret = (pSym.value.vfloat == expr.value.vfloat) ? EQUAL_STATUS : ((pSym.value.vfloat > expr.value.vfloat) ? GREATER_STATUS : LESS_STATUS);
        break;

    case EXPR_INT << 16 | EXPR_FLOAT:
        ret = (pSym.value.vint == expr.value.vfloat) ? EQUAL_STATUS : ((pSym.value.vint > expr.value.vfloat) ? GREATER_STATUS : LESS_STATUS);
        break;

    case EXPR_INT64 << 16 | EXPR_FLOAT:
        ret = (pSym.value.vint64 == expr.value.vfloat) ? EQUAL_STATUS : ((pSym.value.vint64 > expr.value.vfloat) ? GREATER_STATUS : LESS_STATUS);
        break;

    case EXPR_STRING << 16 | EXPR_STRING:
    {
        //都是空
        if (pSym.value.vpoint == nullptr && expr.value.vpoint == nullptr)
        {
            ret = EQUAL_STATUS;
        }
        else if (pSym.value.vpoint != nullptr && expr.value.vpoint != nullptr)
        {
            QString exprStr(*(QByteArray*)expr.value.vpoint);
            if (((QByteArray*)pSym.value.vpoint)->operator==(exprStr))
            {
                ret = EQUAL_STATUS;
            }
            else if (((QByteArray*)pSym.value.vpoint)->operator>(exprStr))
            {
                ret = GREATER_STATUS;
            }
            else
            {
                ret = LESS_STATUS;
            }
        }
        else
        {
            //不空的为大
            ret = ((pSym.value.vpoint != nullptr) ? GREATER_STATUS : LESS_STATUS);
        }
    }
    break;

    case EXPR_U16STRING << 16 | EXPR_U16STRING:
    {
        //都是空
        if (pSym.value.vpoint == nullptr && expr.value.vpoint == nullptr)
        {
            ret = EQUAL_STATUS;
        }
        else if (pSym.value.vpoint != nullptr && expr.value.vpoint != nullptr)
        {
            QString exprStr(*(QString*)expr.value.vpoint);
            int v = ((QString*)pSym.value.vpoint)->compare(exprStr);
            if (v == 0)
            {
                ret = EQUAL_STATUS;
            }
            else if (v > 0)
            {
                ret = GREATER_STATUS;
            }
            else
            {
                ret = LESS_STATUS;
            }
        }
        else
        {
            //不空的为大
            ret = ((pSym.value.vpoint != nullptr) ? GREATER_STATUS : LESS_STATUS);
        }
    }
    break;
    //时间和时间比较
    case EXPR_DATE << 16 | EXPR_DATE:
    {
        if (pSym.value.vpoint == nullptr && expr.value.vpoint == nullptr)
        {
            ret = EQUAL_STATUS;
        }
        else if (pSym.value.vpoint != nullptr && expr.value.vpoint != nullptr)
        {

            QDateTime exprStr(*(QDateTime*)expr.value.vpoint);

#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
            if (*((QDateTime*)pSym.value.vpoint) == exprStr)
            {
                ret = EQUAL_STATUS;
            }
            else if (*((QDateTime*)pSym.value.vpoint) > exprStr)
            {
                ret = GREATER_STATUS;
            }
            else
            {
                ret = LESS_STATUS;
            }
#else

            if (((QDateTime*)pSym.value.vpoint)->operator==(exprStr))
            {
                ret = EQUAL_STATUS;
            }
            else if (((QDateTime*)pSym.value.vpoint)->operator>(exprStr))
            {
                ret = GREATER_STATUS;
            }
            else
            {
                ret = LESS_STATUS;
            }
#endif
        }
        else
        {
            //不空的为大
            ret = ((pSym.value.vpoint != nullptr) ? GREATER_STATUS : LESS_STATUS);
        }
    }
    break;

    case EXPR_BOOL << 16 | EXPR_BOOL:
    {
        ret = (pSym.value.vbool == expr.value.vbool) ? EQUAL_STATUS : UNEQUAL_STATUS;
    }
    break;

    case EXPR_CHAR << 16 | EXPR_CHAR:
    {
        ret = (pSym.value.vchar == expr.value.vchar) ? EQUAL_STATUS : ((pSym.value.vchar > expr.value.vchar) ? GREATER_STATUS : LESS_STATUS);
    }
    break;

    case EXPR_CHAR << 16 | EXPR_WCHAR:
    {
        ret = (QChar(pSym.value.vchar) == QChar(expr.value.vwchar)) ? EQUAL_STATUS : ((QChar(pSym.value.vchar) > QChar(expr.value.vwchar)) ? GREATER_STATUS : LESS_STATUS);
    }
    break;

    case EXPR_WCHAR << 16 | EXPR_WCHAR:
    {
        ret = (pSym.value.vwchar == expr.value.vwchar) ? EQUAL_STATUS : ((pSym.value.vwchar > expr.value.vwchar) ? GREATER_STATUS : LESS_STATUS);
    }
    break;

    case EXPR_WCHAR << 16 | EXPR_CHAR:
    {
        ret = (QChar(pSym.value.vwchar) == QChar(expr.value.vchar)) ? EQUAL_STATUS : ((QChar(pSym.value.vwchar) > QChar(expr.value.vchar)) ? GREATER_STATUS : LESS_STATUS);
    }
    break;

    default:
        //统一视作不能对比。
        if (iswarn)
        {
            QString msg = QString(u8"变量 %1 和表达式只 %2 不能进行类型对比").arg(pSym.toString()).arg(expr.toString());
            std::cout << msg.toStdString() << std::endl;
        }
        break;
    }

    return ret;
}

QString* ExprValue::getU16String()
{
    return (QString*)this->value.vpoint;
}

QChar ExprValue::getQChar()
{
    return QChar(this->value.vwchar);
}

//是否是合法的mapkey
bool ExprValue::isMapKeyType()
{
    switch (type)
    {
    case EXPR_INT:
    case EXPR_INT64:
    case EXPR_CHAR:
    case EXPR_WCHAR:
    case EXPR_STRING:
    case EXPR_U16STRING:
        return true;
    default:
        break;
    }
    return false;
}

void ExprValue::freeMem()
{

        switch (this->type)
        {
        case EXPR_STRING:
        case EXPR_U16STRING:
        case EXPR_DATE:
        case EXPR_STRUCT:
        case EXPR_FUN:
        case EXPR_MEMFUN:
        case EXPR_FILE:
        case HD_TO_HS_INFO:
        case EXPR_CALL_BACK_FUN:
        case EXPR_EXCEL:
        case EXPR_STRUCT_DEC:
        {
            if (value.vpoint == nullptr)
            {
                return;
            }
            switch (type)
            {

                case EXPR_STRING:
                {

                    delete (QByteArray*)value.vpoint;
                    value.vpoint = nullptr;
    #ifdef PIN_MEM_REF
                    freeTimes++;
    #endif
                    return;

                }
                break;
                case EXPR_U16STRING:
                {

                    delete (QString*)value.vpoint;
                    value.vpoint = nullptr;
#ifdef PIN_MEM_REF
                    freeTimes++;
#endif
                    return;

                }
                break;
                case EXPR_STRUCT:
                {
                    STRUCT_VALUE_DATA* pData = (STRUCT_VALUE_DATA*)value.vpoint;
                    if (pData != nullptr)
                    {
                        pData->destory();
                    }
                    delete pData;
                    value.vpoint = nullptr;


    #ifdef PIN_MEM_REF
                    freeTimes++;
    #endif
                    return;
                }

                case EXPR_DATE:
                {
                    //时间也做完全拷贝拉倒。
                    delete (QDateTime*)value.vpoint;
                    value.vpoint = nullptr;

    #ifdef PIN_MEM_REF
                    freeTimes++;
    #endif
                    return;
                }
                case EXPR_MEMFUN:
                {
                    //时间也做完全拷贝拉倒。
                    delete (MEM_FUN_INFO*)value.vpoint;
                    value.vpoint = nullptr;

    #ifdef PIN_MEM_REF
                    freeTimes++;
    #endif
                    return;
                }
                case EXPR_FUN:
                case    HD_TO_HS_INFO:
                case EXPR_CALL_BACK_FUN:
                {

                    delete (std::string*)value.vpoint;
                    value.vpoint = nullptr;

    #ifdef PIN_MEM_REF
                    freeTimes++;
    #endif
                    return;
                }
                //20250215开始，文件和时间，也作为基本变量。不同的是，文件是使用引用计数来管理的，这是和其它基本变量不同的地方。
                case EXPR_FILE:
                {
                    freeFile();
                    return;
                }
                case EXPR_EXCEL:
                {
                    freeExcel();
                    return;
                }
                case EXPR_STRUCT_DEC:
                {

                delete (std::vector<std::string>*)value.vpoint;
#ifdef PIN_MEM_REF
                 freeTimes++;
#endif
                }
                break;
            }
        }
            break;

        case EXPR_LIST:
            freeList();
            break;

        case EXPR_MAP:
            freeMap();
            break;

        default:
            //其它变量务必填充0。这样防止类型修改后，原来的整数做字符串处理。
            //lb= [1,2,3] lb[0] = "4" 这样会触发bug。必须填充0.
            value.vint64 = 0;
            break;
        }

}

void ExprValue::print(std::string name)
{
    switch(type)
    {
    case EXPR_INT:
        std::cout << name << "=" << value.vint << std::endl;
        break;
    case EXPR_INT64:
        std::cout << name << "=" << value.vint64 << std::endl;
        break;
    case EXPR_FLOAT:
        std::cout << name << "=" << value.vfloat << std::endl;
        break;
    case EXPR_STRING:
        std::cout << name << "=" << (std::string*)value.vpoint << std::endl;
        break;
    }
}

void ExprValue::doClearList()
{
    std::vector<ExprValue_*>* pData = (std::vector<ExprValue_*>*)this->value.vpoint;

    for (int i = 0, c = pData->size(); i < c; ++i)
    {
        (*pData)[i]->freeMem();

        delete (*pData)[i];
#ifdef PIN_MEM_REF
        freeTimes++;
#endif
    }
    pData->clear();
}

bool ExprValue::freeList()
{
    if(this->type == EXPR_LIST && this->value.vpoint != nullptr)
    {
        if(0 == subListMapRefNum(this->value.vpoint))
        {
#ifdef PIN_DEBUG
            std::cout << u8"释放列表" << this->value.vpoint << std::endl;
#endif
            std::vector<ExprValue_*>* pData = (std::vector<ExprValue_*>*)this->value.vpoint;

            doClearList();

#if 0
            for(int i=0, c= pData->size(); i <c; ++i)
            {
                (*pData)[i]->freeMem();

                delete (*pData)[i];
#ifdef PIN_MEM_REF
        freeTimes++;
#endif
            }
#endif
            delete pData;
#ifdef PIN_MEM_REF
        freeTimes++;
#endif
            value.vpoint = nullptr;
        }
        else
        {
            value.vpoint = nullptr;
        }

        return true;

    }
    return false;
}

//包裹一下，zd_clear中要复用。
void ExprValue::doClearMap()
{
    std::unordered_map<ExprValue_, ExprValue_*>* pData = (std::unordered_map<ExprValue_, ExprValue_*>*)this->value.vpoint;

    for (std::unordered_map<ExprValue_, ExprValue_*>::iterator it = pData->begin(); it != pData->end(); ++it)
    {
        ExprValue_ key = it->first;
        key.freeMem();

        it->second->freeMem();

        delete it->second;
#ifdef PIN_MEM_REF
        freeTimes++;
#endif
    }
    pData->clear();
}

bool ExprValue::freeMap()
{
    if(this->type == EXPR_MAP && this->value.vpoint != nullptr)
    {

        if(0 == subListMapRefNum(this->value.vpoint))
        {
            doClearMap();

            std::unordered_map<ExprValue_, ExprValue_*>* pData = (std::unordered_map<ExprValue_, ExprValue_*>*)this->value.vpoint;
#if 0
            for (std::unordered_map<ExprValue_, ExprValue_*>::iterator it = pData->begin(); it != pData->end(); ++it)
            {
                ExprValue_ key = it->first;
                key.freeMem();

                it->second->freeMem();

                delete it->second;
#ifdef PIN_MEM_REF
        freeTimes++;
#endif
            }
#endif

            delete pData;
#ifdef PIN_MEM_REF
        freeTimes++;
#endif
            value.vpoint = nullptr;
        }
        else
        {
            value.vpoint = nullptr;
        }

        return true;

    }
    return false;
}

bool ExprValue::freeFile()
{
    if (this->type == EXPR_FILE && this->value.vpoint != nullptr)
    {
        if (0 == subListMapRefNum(this->value.vpoint))
        {
            FILE_VALUE_DATA* pData = (FILE_VALUE_DATA*)this->value.vpoint;

#ifdef PIN_DEBUG

            //std::cout << u8"释放文件" << pData->pFileInfo->absoluteFilePath().toStdString() << std::endl;
#endif
            pData->destory();
            delete pData;
            value.vpoint = nullptr;

#ifdef PIN_MEM_REF
            freeTimes++;
#endif
        }
        else
        {
            value.vpoint = nullptr;
        }

        return true;

    }
    return false;
}

bool ExprValue::freeExcel()
{
    if (this->type == EXPR_EXCEL && this->value.vpoint != nullptr)
    {
        if (0 == subListMapRefNum(this->value.vpoint))
        {
            EXCEL_VALUE_DATA* pData = (EXCEL_VALUE_DATA*)this->value.vpoint;

#ifdef PIN_DEBUG

            //std::cout << u8"释放文件" << pData->pFileInfo->absoluteFilePath().toStdString() << std::endl;
#endif
            pData->destory();
            delete pData;
            value.vpoint = nullptr;

#ifdef PIN_MEM_REF
            freeTimes++;
#endif
        }
        else
        {
            value.vpoint = nullptr;
        }

        return true;

    }
    return false;
}


QString ExprValue::toString()
{

    switch(type)
    {
    case EXPR_INT:
        return QString("%1").arg(value.vint);
    case EXPR_INT64:
        return QString("%1").arg(value.vint64);
    case EXPR_FLOAT:
        return QString("%1").arg(value.vfloat);
    case EXPR_STRING:
    {
        if(value.vpoint != nullptr)
        {
            return QString(*(QByteArray*)value.vpoint);
        }
        return "";
    }
    case EXPR_U16STRING:
    {
        if (value.vpoint != nullptr)
        {
            return *((QString*)value.vpoint);
        }
        return "";
    }
    case EXPR_BOOL:
        return QString("%1").arg(value.vbool ? "zhen":"jia");

    case EXPR_CHAR:
        return QString("%1").arg(value.vchar);
    case EXPR_WCHAR:
        return QString("%1").arg(QChar(value.vwchar));

    case EXPR_STRUCT:
        //打印结构体
        {
            STRUCT_VALUE_DATA* pData =  (STRUCT_VALUE_DATA*)value.vpoint;


            if (pData->pValue != 0)
            {
                QString str = "{";

                std::vector<ExprValue*>* exprVec = (std::vector<ExprValue*>*)(pData->pValue);

                for (int i = 0, c = exprVec->size(); i < c; ++i)
                {
                    ExprValue* v = exprVec->at(i);

                    if (v->type == EXPR_STRING || v->type == EXPR_U16STRING)
                    {
                        str += "\"" + v->toString() + "\"" + ((i != c - 1) ? "," : "");
                    }
                    else
                    {
                        str += v->toString() + ((i != c - 1) ? "," : "");
                    }
                }
                str += "}";
                return str;
            }
            else
            {
                //对于可能是cpp转接的结构体，本身并没有成员变量，按照他们的tostring方法进行打印即可。
                if(-1 != pData->structTypeId)
                {
                    switch (pData->structTypeId)
                    {
                        /*case PString_Struct_Id:
                        {
                            return std::any_cast<QString&>(((STRUCT_VALUE_DATA*)(this->value.vpoint))->pCppObj);
                        }
                        break;*/

#ifdef NDD_PIN_FUN
                        case NddMainWin_Struct_ID:
                        {
                            return "{}";
                        }
                        break;
#endif

                        default:
                        {
                            return "{" + QStr(pData->structType) + "}";
                        }
                        break;
                    }
                }
            }
        }
        break;
    case EXPR_LIST:
        //打印列表
        {
        //assert(value.vpoint != nullptr);
            //这里会报错,结构体互相依赖
            std::vector<ExprValue_*>* exprVec = (std::vector<ExprValue_*>*)value.vpoint;
            if (exprVec == nullptr)
            {
                return "[]";
            }

            QString str = "[";
            for(int i=0,c = exprVec->size(); i < c; ++i)
            {
                //结构体里面的字符串变量，如果是字符串，则加上“”号
                ExprValue_* v = exprVec->at(i);

                if(v->type == EXPR_STRING || v->type == EXPR_U16STRING)
                {
                    str += "\"" + v->toString() + "\"" + ((i!=c-1)?",":"");
                }
                else
                {
                    str += v->toString() + ((i!=c-1)?",":"");
                }
            }
            str += "]";

            return str;
        }
        break;
    case EXPR_MAP:
        //打印列表
        {
            //这里会报错,结构体互相依赖
            std::unordered_map<ExprValue_, ExprValue_*>* pData = (std::unordered_map<ExprValue_, ExprValue_*>*)value.vpoint;

            QString str = "{";

            auto itb = pData->begin();
            for (std::unordered_map<ExprValue_, ExprValue_*>::iterator it = pData->begin(); it != pData->end(); ++it)
            {
                 if(it != itb)
                {
                    str += ", ";
                }

                ExprValue_ key = it->first;
                ExprValue_* v = it->second;

                if(key.type == EXPR_STRING || key.type == EXPR_U16STRING)
                {
                    str += "\"" + key.toString() + "\":";
                }
                else
                {
                    str += key.toString() + ":";
                }

                if(v->type == EXPR_STRING)
                {
                    str += "\"" + v->toString() + "\"";
                }
                else
                {
                    str += v->toString();
                }



            }
            str += "}";

            return str;
        }
        break;
    case EXPR_FILE:
    {
        if(value.vpoint != nullptr)
        {
            FILE_VALUE_DATA* pData = (FILE_VALUE_DATA*)value.vpoint;

            QString ret = QString("file:%1 ").arg(pData->pFileInfo->filePath());

            return ret;
        }
        else
        {
            return "kong";
        }
    }
        break;
    case EXPR_EXCEL:
    {
        if(value.vpoint != nullptr)
        {
            EXCEL_VALUE_DATA_* pData = (EXCEL_VALUE_DATA_*)value.vpoint;

            if(!pData->excelFileName.empty())
            {
                QString ret = QString("excel:%1 ").arg(QStr(pData->excelFileName));

                return ret;
            }
            return "kong";
        }
        else
        {
            return "kong";
        }
    }
    break;
    case EXPR_DATE:
        if(value.vpoint != nullptr)
        {
            QDateTime* pDate = (QDateTime*)value.vpoint;

            QString ret = pDate->toString("yyyy-MM-dd hh:mm:ss");

            return ret;
        }
        else
        {
            return "kong";
        }
        break;
    case EXPR_FUN:
    {
        //文件类型
        if (value.vpoint != nullptr)
        {
            std::string funName = *((std::string*)value.vpoint);
            std::string varName = (this->varName != nullptr) ? (*(this->varName)) : "";

            std::string info = varName + "->" + funName;

            return QString("%1").arg(QStr(info));
        }
        return "kong";
    }
    break;
    default:
        return "";
    }
    return "";
}
    //ExprValue_(const ExprValue_& other) = delete;
    //ExprValue_& operator=(const ExprValue_ & other) = delete;
    //统一做浅拷贝，需要深拷贝的地方，自己去深拷贝调用deepCopy。
//特别注意：文件是个例外，就算深拷贝，也是使用的浅拷贝。还有字典，和列表不应该有深拷贝出现，还是浅拷贝的方式。
//这个名称比较唬人。字典、列表，还是使用的浅拷贝方式。20250311 做了区分。
ExprValue ExprValue::deepCopy(bool isLbMapDeepCopy) const
{
    switch(this->type)
    {
    //字符串的情况。
    case EXPR_STRING:
    {
        ExprValue_ ret;
        ret.type = EXPR_STRING;

        if(this->value.vpoint == nullptr)
        {
            ret.value.vpoint = nullptr;
        }
        else
        {
            ret.value.vpoint = new QByteArray(*(QByteArray*)value.vpoint);
			#ifdef PIN_MEM_REF
            newTime();
#endif
        }

        return ret;
    }
    //字符串的情况。
    case EXPR_U16STRING:
    {
        ExprValue_ ret;
        ret.type = EXPR_U16STRING;

        if (this->value.vpoint == nullptr)
        {
            ret.value.vpoint = nullptr;
        }
        else
        {
            ret.value.vpoint = new QString(*(QString*)value.vpoint);
#ifdef PIN_MEM_REF
            newTime();
#endif
        }

        return ret;
    }
    case EXPR_STRUCT:
    {
        ExprValue_ ret;
        ret.type = EXPR_STRUCT;

        if(this->value.vpoint == nullptr)
        {
            ret.value.vpoint = nullptr;
        }
        else
        {
            STRUCT_VALUE_DATA* pSrc =  (STRUCT_VALUE_DATA*)value.vpoint;

            STRUCT_VALUE_DATA* pNew = pSrc->deepCopy();

            ret.value.vpoint = pNew;
        }

        return ret;
    }
    case EXPR_LIST:
    {
        if (!isLbMapDeepCopy)
        {
            //还是浅拷贝，和文件一样
            ExprValue_ ret;
            ret.type = EXPR_LIST;
            if (this->value.vpoint == nullptr)
            {
                ret.value.vpoint = nullptr;
            }
            else
            {
                ret.value.vpoint = value.vpoint;
                addListMapRefNum(value.vpoint);
            }
            return ret;
        }
        else
        {
            //真正的深拷贝。对列表做深拷贝。
            ExprValue_ ret;
            ret.type = EXPR_LIST;

            std::vector<ExprValue_*>* pData = (std::vector<ExprValue_*>*)this->value.vpoint;

            std::vector<ExprValue_*>* pNew = new std::vector<ExprValue_*>(pData->size());
#ifdef PIN_MEM_REF
            newTime();
#endif
            for (int i = 0, c = pData->size(); i < c; ++i)
            {
                (*pNew)[i] = (*pData)[i]->deepCopy2(true);
            }

            ret.value.vpoint = pNew;
            addListMapRefNum(pNew);

            return ret;
        }
    }
    break;
    case EXPR_MAP:
    {
        if (!isLbMapDeepCopy)
        {
            //还是浅拷贝，和文件一样
            ExprValue_ ret;
            ret.type = EXPR_MAP;
            if (this->value.vpoint == nullptr)
            {
                ret.value.vpoint = nullptr;
            }
            else
            {
                ret.value.vpoint = value.vpoint;
                addListMapRefNum(value.vpoint);
            }

            return ret;
        }
        else
        {

            ExprValue_ ret;
            ret.type = EXPR_MAP;

            std::unordered_map<ExprValue_, ExprValue_*>* pData = (std::unordered_map<ExprValue_, ExprValue_*>*)this->value.vpoint;

            std::unordered_map<ExprValue_, ExprValue_*>* pNew = new std::unordered_map<ExprValue_, ExprValue_*>();
#ifdef PIN_MEM_REF
            newTime();
#endif

            for (std::unordered_map<ExprValue_, ExprValue_*>::iterator it = pData->begin(); it != pData->end(); ++it)
            {
                ExprValue_ key = it->first;
                ExprValue_* v = it->second->deepCopy2(true);

                (*pNew)[key] = v;
            }

            ret.value.vpoint = pNew;
            addListMapRefNum(pNew);

            return ret;
        }
    }
    break;
    case EXPR_DATE:
    {
        ExprValue_ ret;
        ret.type = EXPR_DATE;

        if(this->value.vpoint == nullptr)
        {
            ret.value.vpoint = nullptr;
        }
        else
        {
            ret.value.vpoint = new QDateTime(*(QDateTime*)value.vpoint);
#ifdef PIN_MEM_REF
            newTime();
#endif
        }

        return ret;
    }
    case EXPR_FILE:
    case EXPR_EXCEL:
    {
        //20250215 现在时间和文件也可以做变量或结构体变量,所以针对文件的深拷贝，该如何设计？
        //文件的深拷贝,还是使用浅拷贝，增加引用计数即可。
        ExprValue_ ret;
        ret.type = this->type;
        if(this->value.vpoint == nullptr)
        {
            ret.value.vpoint = nullptr;
        }
        else
        {
            //还是浅拷贝。这里加不加计数，是个问题？这里加了，外面就不加。
            //权衡一下，这里统一加，后续看看是否有问题。
            addListMapRefNum(this->value.vpoint);
            ret.value.vpoint = this->value.vpoint;
        }
        return ret;
    }

    }

    return *this;
}



//和deepCopy2类似，不过返回堆对象
ExprValue* ExprValue::deepCopy2(bool isLbMapDeepCopy)
{
    ExprValue_ *ret = new ExprValue_(deepCopy(isLbMapDeepCopy));
	#ifdef PIN_MEM_REF
            newTime();
#endif
    return ret;
}

#if 0
//结构体可以是字符串，时间，文件和其它基本变量。该函数在访问结构体成员返回时使用。
//需要说，字符串、时间是深拷贝一份内存，而文件是增加引用计数。
void ExprValue::deepCopyStructMemType()
{
    if(type == EXPR_STRING)
    {
        //必须要深拷贝一下，因为返回ExprValue后，外面会释放返回值，所以必须深拷贝一份。避免右值被释放。
        QByteArray* pNew = new QByteArray(*(QByteArray*)ret.value.vpoint);
        ret.value.vpoint = pNew;
#ifdef PIN_MEM_REF
        newTime();
#endif
    }
}
#endif

//和2不一样，是浅拷贝，类似move拷贝函数，把现在的expr浅拷贝，转移其内存到新对象，这样效率更高。
//凡是调用shallowMoveCopy后，外面其实不必要freebasevar,调用也不影响。
ExprValue* ExprValue::shallowMoveCopy()
{
    ExprValue_ *ret = new ExprValue_(*this);
#ifdef PIN_MEM_REF
            newTime();
#endif
    //现在有内存拷贝的类型，就是字符串和结构体
    if(this->type >= EXPR_STRING || this->type == EXPR_STRUCT /*|| this->type == EXPR_LIST || this->type == EXPR_MAP*/)
    {
        this->value.vpoint = nullptr;
    }
    return ret;
}

//这里在加入字典时，判断key是否相等，要走这里。
bool ExprValue::operator==(const ExprValue_& other) const {
    //int int64要单独对待
    if (type != other.type) {

        if((type == EXPR_INT && other.type == EXPR_INT64) || (type == EXPR_INT64 && other.type == EXPR_INT))
        {
            return value.vint64 == other.value.vint64;
        }

        return false;
    }
    switch (type) {
    case EXPR_INT:
    case EXPR_INT64:
        return value.vint64 == other.value.vint64;
    case EXPR_CHAR:
        return value.vchar == other.value.vchar;
    case EXPR_WCHAR:
        return value.vwchar == other.value.vwchar;
    case EXPR_STRING: {
        if (value.vpoint == nullptr && other.value.vpoint == nullptr) {
            return true;
        }
        if (value.vpoint == nullptr || other.value.vpoint == nullptr) {
            return false;
        }
        QByteArray* pb1 = static_cast<QByteArray*>(value.vpoint);
        QByteArray* pb2 = static_cast<QByteArray*>(other.value.vpoint);
        return *pb1 == *pb2;
    }
    case EXPR_U16STRING: {
        if (value.vpoint == nullptr && other.value.vpoint == nullptr) {
            return true;
        }
        if (value.vpoint == nullptr || other.value.vpoint == nullptr) {
            return false;
        }
        QString* pb1 = static_cast<QString*>(value.vpoint);
        QString* pb2 = static_cast<QString*>(other.value.vpoint);
        return *pb1 == *pb2;
    }
    default:
        return false;
    }
}

#if 0
void ExprValue::setTypeName(std::string& typeName)
{

    if (s_packName_map.contains(typeName))
    {
        this->value.vtype = s_packName_map.value(typeName);
    }
    else
    {
        const char* cstr = typeName.c_str();
        char* newStr = new char[strlen(cstr)];
#ifdef PIN_MEM_REF
        newTime();
#endif
        memcpy(newStr,cstr, strlen(cstr)-1);
        newStr[strlen(cstr) - 1] = '\0';
        this->value.vtype = newStr;
    }
}
#endif
